<?php

class Player {
	private $location;
	private $name;
	private $money = 0;
	private $ownedCells = array();
	private $board;
	private $dice_result;
	private $number_of_doubles = 0;
	private $rolled_doubles = false;
	private $cards = array();
	
	public function __construct($name, $start_location, $board = null) {
		$this->name 	= $name;
		$this->location = $start_location;
		$this->board 	= $board;
	}

//Getters

	public function getName()
	{
		return $this->name;
	}
	
	public function getPlayer()
	{
		return $this;
	}
	
	public function getDiceResult()
	{
		return $this->dice_result;
	}
	
	public function getLocation() {
		return $this->location;
	}
	
	public function getMoney()
	{
		return $this->money;
	}

	public function getOwnedCells()
	{
		return $this->ownedCells;
	}

	public function getCards()
	{
		return $this->cards;
	}
	
	public function getNumberOfDoubles()
	{
		return $this->number_of_doubles;
	}
	
	public function getRolledDoubles()
	{
		return $this->rolled_doubles;
	}

//Setters
		
	public function setDiceResult($result)
	{
		$this->dice_result = $result;
	}
	
	public function setLocation($location_cell) {
		$this->location = $location_cell;
	}
		
	public function setLocationByName($location)
	{
		$cell = $this->board->getCellByName($location);
		$this->setLocation($cell);
	}

	public function setMoney($amount)
	{
		$this->money = $amount;
	}

	public function setNumberOfDoubles($amount)
	{
		$this->number_of_doubles = $amount;
	}

	public function setRolledDoubles($value)
	{
		$this->rolled_doubles = $value;
	}

//Adders

	public function addMoney($amount)
	{
		$this->money += $amount;
	}
	
	public function addCard($card)
	{
		$this->cards[] = $card;
	}

	public function addOwnedCell($cell)
	{
		$this->ownedCells[] = $cell;
	}	

//Remove

	public function removeMoney($amount)
	{
		return $this->money -= $amount;
	}

	public function removeCardByValue($value)
	{
		$index = array_search($value, $this->cards);
		$this->removeCardByIndex($index);
	}

	public function removeCardByIndex($index)
	{
	 	unset($this->cards[$index]);
		if(count($this->cards) > 1 )
		{
			//clean up the array keys
			$this->cards = array_values($this->cards);
		}
	}	
	 
//Mortgage

	/**
	 * This function will handle mortgaging a cell owned by the current player
	 * 
	 * @param BoardCell $cell to be mortgaged
	 * 
	 * @return boolean true on success
	 */	
	 public function mortgageCell($cell)
	 {
	 	$result = false;
	 	if(!$cell->isMortgaged() && $cell->getOwner() == $this)
		{
			$cell_value = $cell->getPrice();
			$mort_value = $cell_value * Game::MORTGAGE_PERCENTAGE;
			$this->addMoney($mort_value);
			$cell->setMortgaged();
			
			$result = true;
		}
		return $result;
	 }
	 
	 /**
	  * This function will handle paying back a mortgage on a cell
	  * 
	  * @param BoardCell $cell to un-mortgaged
	  * 
	  * @return boolean true on success	  
	  */
	 public function payMortgage($cell)
	 {
	 	$result = false;
	 	if($cell->isMortgaged() && $cell->getOwner() == $this && $this->getMoney() >= $cell->getPrice())
		{
			$this->removeMoney($cell->getPrice());
			$cell->removeMortgage();
			$result = true;
		}
		return $result;
	 }

//Rent

	/**
	 * This function will be used to determine the cell type and pay rent accordingly. 
	 * 
	 */
	public function payRent()
	{
		$cell = $this->getLocation();
		if($cell->isOwned() && $cell->getOwner() != $this && !$cell->isMortgaged())
		{
			if($cell->getType() == "Property")
			{
				$this->payRentProperty($cell);
			}
			elseif($cell->getType() == "Utility")
			{
				$this->payRentUtility($cell);
			}
			elseif($cell->getType() == "Railroad")
			{
				$this->payRentRailroad($cell);
			}
		}
	}
	
	/**
	 * This function handles paying rent for property cells.
	 * @param object $cell
	 */
	public function payRentProperty($cell)
	{
		$cell_owner = $cell->getOwner();
		$cell_price = $cell->getPrice();
		$cell_color = $cell->getColor();
		
		$ownsAll = $this->board->playerOwnsAllColorCell($cell_owner, $cell_color);
		if($ownsAll)
		{
			$cell_price = $cell_price *2;
		}
		if($this->getMoney() >= $cell_price)
		{
			$cell_owner->addMoney($cell_price);
			$this->removeMoney($cell_price);
		}
		else
		{
			$current_money = $this->getMoney();
			$cell_owner->addMoney($current_money);
			$this->removeMoney($current_money);
		}
	}
	
	/**
	 * This function handles paying rent for utilitie cells
	 * @param object $cell
	 */
	public function payRentUtility($cell)
	{
		$utility_array = $this->board->getCellsByType("Utility");
		$numOwned=0;
		foreach($utility_array as $util)
		{
			if($util->isOwned())
			{
				$numOwned++;
			}
		}
		if($numOwned > 1)
		{
			$rent = $this->getDiceResult() * UtilityCell::ALL_PRICE_MULTIPLIER;
		}
		else
		{
			$rent = $this->getDiceResult() * UtilityCell::SINGLE_PRICE_MULTIPLIER;
		}
		
		if($rent > $this->getMoney())
		{
			$this->setMoney(0);
		}
		else
		{
			$this->removeMoney($rent);
		}
	}
	
	/**
	 * This function handles paying rent for utilitie cells
	 * @param object $cell
	 */	
	public function payRentRailroad($cell)
	{
		$railroad_array = $this->board->getCellsByType("Railroad");
		$cell_owner = $cell->getOwner();
		$numOwned = 0;
		foreach($railroad_array as $rr)
		{
			if($rr->getOwner() == $cell_owner)
			{
				$numOwned ++;
			}
		}
		$rent = 25;
		if($numOwned == 2)
		{
			$rent = 50;
		}
		elseif($numOwned == 3)
		{
			$rent = 100;
		}
		elseif($numOwned == 4)
		{
			$rent = 200;
		}
		else
		{
			$rent = 25;
		}

		if($rent > $this->getMoney())
		{
			$amount = $this->getMoney();
			$cell->getOwner()->addMoney($amount);
			$this->setMoney(0);
		}
		else
		{
			$cell->getOwner()->addMoney($rent);			
			$this->removeMoney($rent);
		}
		
	}

//Cell Actions

	/**
	 * Lands a player on the given cell
	 * 
	 * @param object $location_cell
	 * @return void 
	 */
	public function landOn($location_cell) {
		$this->setLocation($location_cell);
		$this->location->landOnPlayerAction($this);
	}
	
	/**
	 * Lands a player on the given cell
	 * 
	 * @param object $location_cell
	 * @return void 
	 */
	public function passOver($location_cell) {
		$location_cell->passOverPlayerAction($this);
		$this->setLocation($location_cell);
	}
	
	/**
	 * This will purchase the cell.
	 * @return 
	 */
	public function purchaseCell()
	{
		$result = false;
		if(!$this->location->isOwned() && $this->getMoney() >= $this->location->getPrice())
		{
			$this->removeMoney($this->location->getPrice());				
			$this->location->setOwner($this);
			$this->addOwnedCell($this->location);
			
			$result = true;
		}
		
		return $result;
	}
	
//Round Actions

	/**
	 * Player takes their turn
	 * 
	 * @param object $dice dice to be rolled
	 * @param object $mortgage_property [optional] property to be mortgaged
	 * @param boolean $unmortgage property to un-mortgage
	 * 
	 * @return 
	 */
	public function takeTurn($dice, $mortgage_property = null, $un_mortgage = false)
	{
		if($mortgage_property != NULL)
		{
			if(!$un_mortgage) {
				$this->mortgageCell($mortgage_property);
			} else {
				$this->payMortgage($mortgage_property);
			}
		}
		
		$result = $this->rollDice($dice);
		$this->setDiceResult($result);
		return 	$result;
	}
 	
	public function rollDice($dice)
	{
		$total = $dice->roll();
		if($dice->isDouble())
		{
			$this->setNumberOfDoubles($this->getNumberOfDoubles() + 1);
			$this->setRolledDoubles(TRUE);
		}
		else
		{
			$this->setRolledDoubles(FALSE);
		}
		
		return $total;
	}
}